package com.tale.springbootatm.controller;

import com.tale.springbootatm.common.constant.StatusCode;
import com.tale.springbootatm.common.util.R;
import com.tale.springbootatm.entity.TransactionRecord;
import com.tale.springbootatm.entity.User;
import com.tale.springbootatm.dao.TransactionRecordRep;
import com.tale.springbootatm.service.UserService;
import com.tale.springbootatm.common.vo.ParamsVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * author: 蔡奇峰
 * date: 2020/4/12 22:57
 * @Version V1.0
 **/
@RestController
@RequestMapping("/transaction")
public class TransactionController {

    @Autowired
    private TransactionRecordRep transactionRecordRep;
    @Autowired
    private UserService userService;


    /**
     * 转账（包含交易记录）
     * @param paramsVO
     * @return
     */
    @PostMapping("/transfer")
    public R transfer(@RequestBody ParamsVO paramsVO){
        if (ObjectUtils.isEmpty(paramsVO)){
            return R.fail().message(StatusCode.TRANSFER_NULL);
        }
        // 转账的卡
        int bankCard = paramsVO.getBankCard();
        // 转账给的卡
        int otherCard = paramsVO.getOtherCard();
        // 转账金额
        int amount = paramsVO.getAmount();

        if (bankCard == otherCard){
            return R.fail().message("对不起！自己不能转账给自己");
        }

        User currentUser = null;
        User transferToUser = null;

        // 传入的参数没有卡号
        if (bankCard == 0 || otherCard == 0){
            return R.fail().message(StatusCode.TRANSFER_ERROR);
        }

        User user = userService.getOne(otherCard);
        // 转账卡号不存在
        if (ObjectUtils.isEmpty(user)){
            return R.fail().message(StatusCode.NONE_CARD);
        }


        // 更新转账者的账户余额
        currentUser = userService.getOne(bankCard);
        double currentBalance = currentUser.getBalance();
        currentBalance = currentBalance - amount;
        if (currentBalance < 0 ){
            return R.fail().message(StatusCode.NOT_MONEY);
        }

        // 更新账户余额
        transferToUser = userService.getOne(otherCard);
        double transferBalance = transferToUser.getBalance();
        transferBalance = transferBalance + amount;
        int i = userService.updateBalance(bankCard, currentBalance);
        if (i <= 0){
            return R.fail().message(StatusCode.TRANSFER_ERROR);
        }

        int flag = userService.updateBalance(otherCard, transferBalance);
        if (flag <= 0){
            return R.fail().message(StatusCode.TRANSFER_ERROR);
        }
        // 保存交易记录
        boolean recordFlag = transferRecord(bankCard, otherCard, 0, amount);


        return R.success().message("转账成功！交易金额：" + amount);
    }


    /**
     * 一次转账记录（转账方和被转账方的交易记录）
     * @param bankCard  转账方卡号
     * @param otherCard 被转账方卡号
     * @param flag 是否打印凭据 1 打印 0 没有
     * @param amount 转账金额
     * @return
     */
    public boolean transferRecord(int bankCard, int otherCard, int flag, double amount){
        Date date = new Date();
        TransactionRecord record = new TransactionRecord(bankCard, flag, amount, "-" + amount + "（转）", date);
        TransactionRecord other = new TransactionRecord(otherCard, flag, amount, "+" + amount + "（转）", date);

        TransactionRecord save = transactionRecordRep.save(record);
        if (ObjectUtils.isEmpty(save)){
            return false;
        }
        TransactionRecord otherFlag = transactionRecordRep.save(other);
        if (ObjectUtils.isEmpty(otherFlag)){
            return false;
        }

        return true;
    }


    /**
     * 账单查询
     * @param record
     * @return
     */
    @PostMapping("/record")
    public R findTransaction(@RequestBody TransactionRecord record){
        if (ObjectUtils.isEmpty(record)){
            return R.fail().message(StatusCode.OBJECT_NULL_MSG).code(StatusCode.OBJECT_NULL);
        }
        int bankCard = record.getBankCard();


        // 分页 只显示7条记录
        Pageable pageable = PageRequest.of(0, 7, Sort.Direction.DESC, "id");
        List<TransactionRecord> list = transactionRecordRep.orderDatePage(bankCard, pageable).getContent();

        return R.success().data("list", list);
    }


    /**
     * 打印凭条（实际上就是最近的一条交易记录)
     * @param record
     * @return
     */
    @PostMapping("/print")
    public R printVoucher(@RequestBody TransactionRecord record){

        if (! ObjectUtils.isEmpty(record) && record.getBankCard() != 0) {

            List<TransactionRecord> list = transactionRecordRep.findNearest(record.getBankCard());

            // 这里的比较有溢出的风险  long转int
            // t1 t2位置相反则降序，当前即为降序
            list = list.stream().sorted((t1, t2) -> (int) (t2.getId() - t1.getId()))
                    .limit(1).collect(Collectors.toList());

            TransactionRecord one = list.get(0);

            // 加密卡号后三位
            String card = one.getBankCard() + "";
            card = card.substring(0, 2) + "***";

            String voucher = "卡号：" + card + "\n" +
                    "交易时间：" + one.getTransactionDate() + "\n" +
                    "交易金额：" + one.getMoney();
            return R.success().data("one", voucher);
        }else {
            return R.fail();
        }
    }

    /**
     * 存款
     * @param transactionRecord
     * @return
     */
    @PostMapping("/deposit")
    public R deposit(@RequestBody TransactionRecord transactionRecord){
        // 获取交易金额
        double amount = transactionRecord.getAmount();
        int bankCard = transactionRecord.getBankCard();
        if (amount <= 0){
            return R.fail().message(StatusCode.DEPOSIT_AMOUNT_ERROR);
        }

        User one = userService.getOne(bankCard);
        // 空对象
        if (ObjectUtils.isEmpty(one)) {

            return R.fail().message(StatusCode.DEPOSIT_NULL);
        }
        // 加钱
        double balance = one.getBalance();
        balance = balance + amount;

        int flag = userService.updateBalance(bankCard, balance);
        if (flag < 0){
            return R.fail().message(StatusCode.DEPOSIT_ERROR);
        }

        String money = "+" + amount;
        transactionRecord.setMoney(money);
        Date nowDate = new Date();
        transactionRecord.setTransactionDate(nowDate);
        TransactionRecord save = transactionRecordRep.save(transactionRecord);
        if (ObjectUtils.isEmpty(save)){
            return R.fail().message("对不起！存款失败！请取回您的钞票！");
        }

        return R.success().message("存款" + amount + "元");
    }

}
